Playing Jenga with the elves
First, create the bricks
input <- read_lines("Day22Sample.txt")
bricks<-as.data.frame(matrix(ncol=6,nrow=0))
for(i in 1:length(input)){
bricks<-rbind(bricks,as.numeric(unlist(str_split(str_replace(input[i],"~",","),","))))}
colnames(bricks)<-c("x1","y1","z1","x2","y2","z2")
### add 1 because working with R instead of a language that starts at 0.
bricks<-bricks+1
Now, sort the bricks by the lowest Z, then add a number to show which block is first (& so on)
bricks <- bricks %>% rowwise %>% mutate(lowz=min(z1,z2)) %>% arrange(lowz) %>%
rowid_to_column(var="bricknum") %>% mutate(bricknum=paste0("brick",bricknum))
bricks[1:5,]
With the bricks sorted, creating an artifical “tower” for them to settle into. It will be a three dimensional array and the lowest layer will be “floor”
Create Container and Graph (mostly for part 2)
tower <- array(character(),
c(max(bricks$x1,bricks$x2),
max(bricks$y1,bricks$y2),
max(bricks$z1,bricks$z2)))
tower[,,1]<-"floor"
Function to settle the blocks into the tower and create a support graph:
settle<-function(blist,twr){
### create a support graph
supportgraph<-matrix(ncol=2,nrow=0)
### create a new dataframe
tinyb<-as.data.frame(matrix(ncol=9,nrow=0))
### for each row of the bricklist
for(i in 1:nrow(blist)){
keepgoing<-TRUE
currbr<-blist[i,]
howmanylevels<-dim(twr)[3]
for(x in currbr$x1:currbr$x2){
for(y in currbr$y1:currbr$y2){
for(z in currbr$z1:currbr$z2){
highestfilled<-max(which(!is.na(twr[x,y,1:(currbr$lowz-1)])))
howmanylevels<-min(howmanylevels,z-highestfilled-1)}}}
currbr$z1<-currbr$z1-howmanylevels
currbr$z2<-currbr$z2-howmanylevels
currbr$lowz<-currbr$lowz-howmanylevels
### once it has dropped as far as possible, add the brickname to the tower
for(x in currbr$x1:currbr$x2){
for(y in currbr$y1:currbr$y2){
for(z in currbr$z1:currbr$z2){
twr[x,y,z]<-currbr$bricknum
if(!is.na(twr[x,y,(z-1)])){supportgraph<-rbind(supportgraph,c(twr[x,y,(z-1)],currbr$bricknum))}
}}}
### add the new brick position to the new bricklist
tinyb<-rbind(tinyb,currbr)}
### clean up the repeat edges in the support graph & create the support graph
supportgraph <- unique(supportgraph)
supportgraph <-simplify(graph_from_edgelist(as.matrix(supportgraph)))
colnames(tinyb)<-colnames(blist)
### return the updated tower, the new bricklist and the list of all connections between bricks
list(twr,tinyb,supportgraph)}
Run on the data
settling<-settle(bricks,tower)
settledbricks<-settling[[2]]
settledtower<-settling[[1]]
settledgraph<-settling[[3]]
Here’s a visual of the real data both before and after settling:
3D plot